/**
  ******************************************************************************
  * @file    IO_Toggle/main.c 
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    23-March-2012
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx.h"
#include "main.h"
/** @addtogroup STM32F0_Discovery_Peripheral_Examples
  * @{
  */

/** @addtogroup IO_Toggle
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
	
void  Key_Init(void)
{
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Pin = GPIO_KEY_PIN;
  GPIO_Init(GPIO_KEY, &GPIO_InitStructure);
}

U8  Read_Key(void)
{
	U8 key = 0;
	
	key = (GPIO_KEY->IDR & GPIO_KEY_PIN) == 0 ? 1 : 0;
	return key;
}

void	LED_Addr_Init(void)
{
	  /* Configure PB9 in output pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_LED_RED_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIO_LED_RED, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_LED_ORG_PIN;
  GPIO_Init(GPIO_LED_ORG, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_LED_BLUE_PIN|GPIO_LED_GREEN_PIN;
  GPIO_Init(GPIO_LED_BLUE_GREEN, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Pin = GPIO_ADDR_PIN;
  GPIO_Init(GPIO_ADDR, &GPIO_InitStructure);
	
}

U8	GetAddr(void)
{
	U8	Addr = 0;

	Addr = GPIO_ReadInputData(GPIO_ADDR) >> 5 & 0x0F;

	return Addr;
}

void	DisplayLED(void)
{
	Led_Ctrl.STATUS.BIT.Red =(Led_Ctrl.STATUS.BIT.Red) ^ (Led_Ctrl.FLS.BIT.Red);
	Led_Ctrl.STATUS.BIT.Orange =(Led_Ctrl.STATUS.BIT.Orange) ^ (Led_Ctrl.FLS.BIT.Orange);
	Led_Ctrl.STATUS.BIT.Blue =(Led_Ctrl.STATUS.BIT.Blue) ^(Led_Ctrl.FLS.BIT.Blue);
	Led_Ctrl.STATUS.BIT.Green =(Led_Ctrl.STATUS.BIT.Green) ^(Led_Ctrl.FLS.BIT.Green);
	if (Led_Ctrl.STATUS.BIT.Red == LEDON)
		GPIO_ResetBits(GPIO_LED_RED, GPIO_LED_RED_PIN);
	else
		GPIO_SetBits(GPIO_LED_RED, GPIO_LED_RED_PIN);
	if (Led_Ctrl.STATUS.BIT.Orange == LEDON)
		GPIO_ResetBits(GPIO_LED_ORG, GPIO_LED_ORG_PIN);
	else
		GPIO_SetBits(GPIO_LED_ORG,	GPIO_LED_ORG_PIN);
	if (Led_Ctrl.STATUS.BIT.Blue == LEDON)
		GPIO_ResetBits(GPIO_LED_BLUE_GREEN, GPIO_LED_BLUE_PIN);
	else
		GPIO_SetBits(GPIO_LED_BLUE_GREEN,	GPIO_LED_BLUE_PIN);
	if (Led_Ctrl.STATUS.BIT.Green == LEDON)
		GPIO_ResetBits(GPIO_LED_BLUE_GREEN, GPIO_LED_GREEN_PIN);
	else
		GPIO_SetBits(GPIO_LED_BLUE_GREEN,	GPIO_LED_GREEN_PIN);
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(MONITOR_TIMER, TIM_IT_Update) != 0)   //?????TIM??????:TIM ??? 
	{
		MONITOR_TIMER->SR = (uint16_t)~TIM_IT_Update; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		
		Led_Ctrl.FLS.Byte = GetAddr();
//		Get_Sensor();

		if(Led_Ctrl.LED_Flash_Time == 0)
		{
			DisplayLED();
			Led_Ctrl.LED_Flash_Time = LED_FLASH_TIME;
		}
		else
			Led_Ctrl.LED_Flash_Time --;
	}		 
}

void PERIOD_TIMER_Init(TIM_TypeDef* TIMx, U8 irq,U16 arr,U16 psc,FunctionalState dis)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	TIM_TimeBaseStructure.TIM_Period = arr; 
	TIM_TimeBaseStructure.TIM_Prescaler = psc;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 
	TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);
 
	TIMx->SR = (uint16_t)~TIM_IT_Update;  //??TIMx???????:TIM ??? 	 
	TIM_ITConfig(TIMx,TIM_IT_Update,ENABLE ); 

	NVIC_InitStructure.NVIC_IRQChannel = irq; 
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
	NVIC_InitStructure.NVIC_IRQChannelPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	TIM_Cmd(TIMx, dis);
}

void InitMonitorTimer(U16 arr,U16 psc)
{
#if 1
	MONITOR_PeriphClockCmd_Enable();
	PERIOD_TIMER_Init(MONITOR_TIMER,MONITOR_IRQ,arr,psc,ENABLE);
#else
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	MONITOR_PeriphClockCmd_Enable();
	TIM_TimeBaseStructure.TIM_Period = arr; 
	TIM_TimeBaseStructure.TIM_Prescaler = psc;
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 
	TIM_TimeBaseInit(MONITOR_TIMER, &TIM_TimeBaseStructure);
 
	MONITOR_TIMER->SR = (uint16_t)~TIM_IT_Update;  //??TIMx???????:TIM ??? 	 
	TIM_ITConfig(MONITOR_TIMER,TIM_IT_Update,ENABLE ); 

	NVIC_InitStructure.NVIC_IRQChannel = MONITOR_IRQ; 
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 
	NVIC_InitStructure.NVIC_IRQChannelPriority = 5;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	TIM_Cmd(MONITOR_TIMER, ENABLE);	
#endif	
}

__INLINE void InitPMOS1Timer(U16 arr,U16 psc)
{
	PERIOD_TIMER_Init(PMOS1_TIMER,PMOS1_IRQ,arr,psc,DISABLE);
}

__INLINE void	PMOS1TimerStart(U16 timer)
{
	pmos1.time = timer;
	pmos1.busy = TRUE;
	GPIO_SetBits(GPIO_PMOS1, GPIO_PMOS1_PIN);
	TIM_Cmd(PMOS1_TIMER, ENABLE);	
}

__INLINE void	PMOS1TimerStop(void)
{
	GPIO_ResetBits(GPIO_PMOS1, GPIO_PMOS1_PIN);
	TIM_Cmd(PMOS1_TIMER, DISABLE);	
	pmos1.busy = FALSE;
}

void	TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(PMOS1_TIMER, TIM_IT_Update) != 0)   //?????TIM??????:TIM ??? 
	{
		PMOS1_TIMER->SR = (uint16_t)~TIM_IT_Update; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		if (pmos1.time >0 )
			pmos1.time --;
		if (pmos1.time == 0)
		{
			PMOS1TimerStop();
			Led_Ctrl.FLS.BIT.Orange = LED_FLASH_ON;
			ErrorCode.BIT.DS3 = TRUE;
		}
	}
}
__INLINE void InitPMOS2Timer(U16 arr,U16 psc)
{
	PERIOD_TIMER_Init(PMOS2_TIMER,PMOS2_IRQ,arr,psc,DISABLE);
}

__INLINE void	PMOS2TimerStart(U16 timer)
{
	pmos2.time = timer;
	pmos2.busy = TRUE;
	GPIO_SetBits(GPIO_PMOS2, GPIO_PMOS2_PIN);
	TIM_Cmd(PMOS2_TIMER, ENABLE);	
}

__INLINE void	PMOS2TimerStop(void)
{
	TIM_Cmd(PMOS2_TIMER, DISABLE);	
	GPIO_ResetBits(GPIO_PMOS2, GPIO_PMOS2_PIN);
	pmos2.busy = FALSE;	
}

void	TIM6_DAC_IRQHandler(void)
{
	if (TIM_GetITStatus(PMOS2_TIMER, TIM_IT_Update) != 0)   //?????TIM??????:TIM ??? 
	{
		PMOS2_TIMER->SR = (uint16_t)~TIM_IT_Update; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		if (pmos2.time >0 )
			pmos2.time --;
		if (pmos2.time == 0)
		{
			PMOS2TimerStop();
			Led_Ctrl.FLS.BIT.Blue = LED_FLASH_ON;
			ErrorCode.BIT.DS1 = TRUE;
		}
	}
}

__INLINE void InitDMotor1Timer(U16 arr,U16 psc)
{
	PERIOD_TIMER_Init(DMotor1_TIMER,DMotor1_IRQ,arr,psc,DISABLE);
}

__INLINE void	DMotor1TimerStart(U16 timer)
{
	dmotor1.time = timer;
	dmotor1.busy = TRUE;
	GPIO_SetBits(GPIO_DCM1IN1, GPIO_DCM1IN1_PIN);
	GPIO_ResetBits(GPIO_DCM1IN2, GPIO_DCM1IN2_PIN);
	TIM_Cmd(DMotor1_TIMER, ENABLE);	
}

__INLINE void	DMotor1TimerStop(void)
{
	TIM_Cmd(DMotor1_TIMER, DISABLE);	
	GPIO_ResetBits(GPIO_DCM1IN1, GPIO_DCM1IN1_PIN);
	GPIO_ResetBits(GPIO_DCM1IN2, GPIO_DCM1IN2_PIN);
	dmotor1.busy = FALSE;
}

void	TIM14_IRQHandler(void)
{
	if (TIM_GetITStatus(DMotor1_TIMER, TIM_IT_Update) != 0)   //?????TIM??????:TIM ??? 
	{
		DMotor1_TIMER->SR = (uint16_t)~TIM_IT_Update; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		if (dmotor1.time >0 )
			dmotor1.time --;
		if (dmotor1.time == 0)
		{
			DMotor1TimerStop();
			Led_Ctrl.FLS.BIT.Green = LED_FLASH_ON;
			ErrorCode.BIT.SealMotor = TRUE;
		}
	}
}

__INLINE void InitDMotor2Timer(U16 arr,U16 psc)
{
	PERIOD_TIMER_Init(DMotor2_TIMER,DMotor2_IRQ,arr,psc,DISABLE);
}

__INLINE void	DMotor2TimerStart(U16 timer)
{
	dmotor2.time = timer;
	dmotor2.busy = TRUE;
	GPIO_SetBits(GPIO_DCM2IN1, GPIO_DCM2IN1_PIN);
	GPIO_ResetBits(GPIO_DCM2IN2, GPIO_DCM2IN2_PIN);
	TIM_Cmd(DMotor2_TIMER, ENABLE);	
}

__INLINE void	DMotor2TimerStop(void)
{
	TIM_Cmd(DMotor2_TIMER, DISABLE);	
	GPIO_ResetBits(GPIO_DCM2IN1, GPIO_DCM2IN1_PIN);
	GPIO_ResetBits(GPIO_DCM2IN2, GPIO_DCM2IN2_PIN);
	dmotor2.busy = FALSE;
}

void	TIM15_IRQHandler(void)
{
	if (TIM_GetITStatus(DMotor2_TIMER, TIM_IT_Update) != 0)   //?????TIM??????:TIM ??? 
	{
		DMotor2_TIMER->SR = (uint16_t)~TIM_IT_Update; //TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		if (dmotor2.time >0 )
			dmotor2.time --;
		if (dmotor2.time == 0)
		{
			DMotor2TimerStop();
			Led_Ctrl.FLS.BIT.Red = LED_FLASH_ON;
			ErrorCode.BIT.FS4 = TRUE;
		}
	}
}

void	MOS_DCMotor_Init(void)
{
  GPIO_InitStructure.GPIO_Pin = GPIO_PMOS1_PIN |GPIO_PMOS2_PIN|GPIO_DCM1IN1_PIN|GPIO_DCM1IN2_PIN|GPIO_DCM2IN1_PIN|GPIO_DCM2IN2_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIO_PMOS1, &GPIO_InitStructure);
	GPIO_ResetBits(GPIO_PMOS1, GPIO_PMOS1_PIN |GPIO_PMOS2_PIN|GPIO_DCM1IN1_PIN|GPIO_DCM1IN2_PIN|GPIO_DCM2IN1_PIN|GPIO_DCM2IN2_PIN);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM6|RCC_APB1Periph_TIM14, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
	InitPMOS1Timer(999,4799);
	InitPMOS2Timer(999,4799);
	InitDMotor1Timer(999,4799);
	InitDMotor2Timer(999,4799);
}

void	Board_Init(void)
{
	  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOC|RCC_AHBPeriph_GPIOF, ENABLE);
//  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
	LED_Addr_Init();
	Led_Ctrl.FLS.Byte = ALL_LED_FLASH_OFF;
	Led_Ctrl.STATUS.Byte = ALL_LEDOFF;
	Led_Ctrl.STATUS.BIT.Red = LEDON;
	Led_Ctrl.LED_Flash_Time = LED_FLASH_TIME;
	DisplayLED();
	MOS_DCMotor_Init();
	Key_Init();
}

void	Check_Error(void)
{
	while(ErrorCode.value != 0)
	{

	}
	Led_Ctrl.FLS.Byte = ALL_LED_FLASH_OFF;
	Led_Ctrl.STATUS.Byte = ALL_LEDOFF;
	Led_Ctrl.STATUS.BIT.Red = LEDON;
}
extern	void	TxSendBuffer(U8	*lpbuff,U8	length);

void	Ram_Init(void)
{
	ErrorCode.value = 0;
	DeviceSts.working = 0;
	return;
}

int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f0xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f0xx.c file
     */
	Board_Init();
	Ram_Init();
	InitMonitorTimer(999,4799);
//	Led_Ctrl.FLS.Byte = ALL_LED_FLASH_ON;
//	ENABLE_TX();

  /* To achieve GPIO toggling maximum frequency, the following  sequence is mandatory. 
     You can monitor PC8 and PC9 on the scope to measure the output signal. 
     If you need to fine tune this frequency, you can add more GPIO set/reset 
     cycles to minimize more the infinite loop timing.
     This code needs to be compiled with high speed optimization option.  */
  while (1)
  {
//		Check_Error();
	if (Read_Key() == 1)
	{
		DeviceSts.working ^= 1;
		if (DeviceSts.working)
		{
			GPIO_SetBits(GPIO_PMOS2, GPIO_PMOS2_PIN);
			GPIO_SetBits(GPIO_PMOS1, GPIO_PMOS1_PIN);
		}
		else
		{
			GPIO_ResetBits(GPIO_PMOS2, GPIO_PMOS2_PIN);
			GPIO_ResetBits(GPIO_PMOS1, GPIO_PMOS1_PIN);
		}
	}

#if 	0
		if ((pmos1.busy == FALSE) && SensorNow.BIT.DS3)
		{
			if (!ErrorCode.BIT.DS3)
				PMOS1TimerStart(100);
		}
		else if (SensorNow.BIT.DS3 == FALSE)
		{
			PMOS1TimerStop();
		}	
		if ((pmos2.busy == FALSE) && SensorNow.BIT.DS1)
		{
			if (!ErrorCode.BIT.DS1)
				PMOS2TimerStart(100);
		}
		else if (SensorNow.BIT.DS1 == FALSE)
		{
			PMOS2TimerStop();
		}	
		if ((dmotor1.busy == FALSE) && SensorNow.BIT.Seal)
		{
			if (!ErrorCode.BIT.SealMotor)
				DMotor1TimerStart(100);
		}
		else if (SensorNow.BIT.Seal == FALSE)
		{
			DMotor1TimerStop();
		}			
		if ((dmotor2.busy == FALSE) && SensorNow.BIT.FS4)
		{
			if (!ErrorCode.BIT.FS4)
				DMotor2TimerStart(100);
		}
		else if (SensorNow.BIT.FS4 == FALSE)
		{
			DMotor2TimerStop();
		}	
		if ((StepMotor1.Busy == FALSE) && SensorNow.BIT.DS2)
		{
			if (!ErrorCode.BIT.DS2)
				StepMotorRun(1000,0,0,1);
		}
		if ((StepMotor2.Busy == FALSE) && SensorNow.BIT.FS6)
		{
			if (!ErrorCode.BIT.FS6)
				StepMotorRun(1000,0,0,2);
		}
#endif		
//		TxSendBuffer("asflj",5);
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
